const dayjs = require('dayjs');
const Sequelize = require('sequelize');
const db = require('../dbProxy');
const config = require('./config');
const utils = require('./utils');

/**
 * 设备管理器（简化版）
 * 合并了 Monitor 和 Strategy 的核心功能
 */
class DeviceManager {
    constructor() {
        // 设备状态 { sn_code: { isOnline, lastHeartbeat, lastSearch, lastApply, lastChat, dailyCounts } }
        this.devices = new Map();
        
        // 系统统计
        this.stats = {
            totalDevices: 0,
            onlineDevices: 0,
            totalTasks: 0,
            completedTasks: 0,
            failedTasks: 0,
            startTime: new Date()
        };
    }

    /**
     * 初始化
     */
    async init() {
        console.log('[设备管理器] 初始化中...');
        await this.loadStats();
        console.log('[设备管理器] 初始化完成');
    }

    /**
     * 加载统计数据
     */
    async loadStats() {
        try {
            const devices = await db.getModel('pla_account').findAll();
            this.stats.totalDevices = devices.length;

            const completedCount = await db.getModel('task_status').count({
                where: { status: 'completed' }
            });
            const failedCount = await db.getModel('task_status').count({
                where: { status: 'failed' }
            });

            this.stats.completedTasks = completedCount;
            this.stats.failedTasks = failedCount;
            this.stats.totalTasks = completedCount + failedCount;
        } catch (error) {
            console.error('[设备管理器] 加载统计失败:', error);
        }
    }

    /**
     * 记录心跳
     */
    async recordHeartbeat(sn_code, heartbeatData = {}) {
        const now = Date.now();
        if (!this.devices.has(sn_code)) {
            this.devices.set(sn_code, {
                isOnline: true,
                lastHeartbeat: now,
                dailyCounts: { date: utils.getTodayString(), searchCount: 0, applyCount: 0, chatCount: 0 }
            });
        }

        const device = this.devices.get(sn_code);
        device.isOnline = true;
        device.lastHeartbeat = now;
    }

    /**
     * 检查设备是否在线
     */
    isDeviceOnline(sn_code) {
        const device = this.devices.get(sn_code);
        if (!device) return false;

        const elapsed = Date.now() - device.lastHeartbeat;
        if (elapsed > config.monitoring.heartbeatTimeout) {
            device.isOnline = false;
            return false;
        }
        return device.isOnline;
    }

    /**
     * 检查是否可以执行操作
     */
    canExecuteOperation(sn_code, operationType) {
        // 检查工作时间
        if (!config.isWorkingHours()) {
            return { allowed: false, reason: '不在工作时间内' };
        }

        // 检查频率限制
        const device = this.devices.get(sn_code);
        if (device) {
            const lastTime = device[`last${operationType.charAt(0).toUpperCase() + operationType.slice(1)}`] || 0;
            const interval = config.getRateLimit(operationType);
            if (Date.now() - lastTime < interval) {
                return { allowed: false, reason: '操作过于频繁' };
            }
        }

        // 检查日限制
        if (device && device.dailyCounts) {
            const today = utils.getTodayString();
            if (device.dailyCounts.date !== today) {
                device.dailyCounts = { date: today, searchCount: 0, applyCount: 0, chatCount: 0 };
            }
            const countKey = `${operationType}Count`;
            const current = device.dailyCounts[countKey] || 0;
            const max = config.getDailyLimit(operationType);
            if (current >= max) {
                return { allowed: false, reason: `今日${operationType}操作已达上限` };
            }
        }

        return { allowed: true };
    }

    /**
     * 记录操作
     */
    recordOperation(sn_code, operationType) {
        const device = this.devices.get(sn_code) || {};
        device[`last${operationType.charAt(0).toUpperCase() + operationType.slice(1)}`] = Date.now();
        
        if (device.dailyCounts) {
            const countKey = `${operationType}Count`;
            device.dailyCounts[countKey] = (device.dailyCounts[countKey] || 0) + 1;
        }
        
        this.devices.set(sn_code, device);
    }

    /**
     * 记录任务开始
     */
    recordTaskStart(sn_code, task) {
        // 简化实现，只记录日志
        console.log(`[设备管理器] 设备 ${sn_code} 开始执行任务: ${task.taskName}`);
    }

    /**
     * 记录任务完成
     */
    recordTaskComplete(sn_code, task, success, duration) {
        if (success) {
            this.stats.completedTasks++;
        } else {
            this.stats.failedTasks++;
        }
        this.stats.totalTasks++;
        console.log(`[设备管理器] 设备 ${sn_code} 任务${success ? '成功' : '失败'}: ${task.taskName} (${duration}ms)`);
    }

    /**
     * 获取系统统计
     */
    getSystemStats() {
        const onlineCount = Array.from(this.devices.values()).filter(d => d.isOnline).length;
        return {
            ...this.stats,
            onlineDevices: onlineCount,
            uptime: utils.formatDuration(Date.now() - this.stats.startTime.getTime())
        };
    }

    /**
     * 获取所有设备状态
     */
    getAllDevicesStatus() {
        const result = {};
        for (const [sn_code, device] of this.devices.entries()) {
            result[sn_code] = {
                isOnline: device.isOnline,
                lastHeartbeat: device.lastHeartbeat,
                dailyCounts: device.dailyCounts || {}
            };
        }
        return result;
    }

    /**
     * 检查心跳状态（异步更新数据库）
     */
    async checkHeartbeatStatus() {
        try {
            const now = Date.now();
            const device_status = db.getModel('device_status');
            const offlineDevices = [];

            for (const [sn_code, device] of this.devices.entries()) {
                if (now - device.lastHeartbeat > config.monitoring.heartbeatTimeout) {
                    // 如果之前是在线状态，现在检测到离线，需要更新数据库
                    if (device.isOnline) {
                        device.isOnline = false;
                        offlineDevices.push(sn_code);
                    }
                }
            }

            // 批量更新数据库中的离线设备状态
            if (offlineDevices.length > 0) {
                await device_status.update(
                    { isOnline: false },
                    {
                        where: {
                            sn_code: {
                                [Sequelize.Op.in]: offlineDevices
                            },
                            isOnline: true  // 只更新当前在线的设备，避免重复更新
                        }
                    }
                );
                console.log(`[设备管理器] 检测到 ${offlineDevices.length} 个设备心跳超时，已同步到数据库: ${offlineDevices.join(', ')}`);
            }

            // 同时检查数据库中的设备状态（处理内存中没有但数据库中有心跳超时的情况）
            const heartbeatTimeout = config.monitoring.heartbeatTimeout;
            const heartbeatThreshold = new Date(now - heartbeatTimeout);

            const timeoutDevices = await device_status.findAll({
                where: {
                    isOnline: true,
                    lastHeartbeatTime: {
                        [Sequelize.Op.lt]: heartbeatThreshold
                    }
                },
                attributes: ['sn_code', 'lastHeartbeatTime']
            });

            if (timeoutDevices.length > 0) {
                const timeoutSnCodes = timeoutDevices.map(dev => dev.sn_code);
                await device_status.update(
                    { isOnline: false },
                    {
                        where: {
                            sn_code: {
                                [Sequelize.Op.in]: timeoutSnCodes
                            }
                        }
                    }
                );
                console.log(`[设备管理器] 从数据库检测到 ${timeoutSnCodes.length} 个心跳超时设备，已更新为离线: ${timeoutSnCodes.join(', ')}`);
            }
        } catch (error) {
            console.error('[设备管理器] 检查心跳状态失败:', error);
        }
    }

    /**
     * 重置所有日计数器
     */
    resetAllDailyCounters() {
        const today = utils.getTodayString();
        for (const device of this.devices.values()) {
            if (device.dailyCounts && device.dailyCounts.date !== today) {
                device.dailyCounts = { date: today, searchCount: 0, applyCount: 0, chatCount: 0 };
            }
        }
    }

    /**
     * 清理离线设备
     */
    cleanupOfflineDevices(threshold = 3600000) {
        const now = Date.now();
        for (const [sn_code, device] of this.devices.entries()) {
            if (now - device.lastHeartbeat > threshold) {
                this.devices.delete(sn_code);
            }
        }
    }
}

// 导出单例
const deviceManager = new DeviceManager();
module.exports = deviceManager;

